home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / hdf / unix / hdf3_2r2.lha / HDF3.2r2 / src / vgp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-28  |  36.9 KB  |  1,655 lines

  1. /***************************************************************************
  2. *
  3. *
  4. *                         NCSA HDF version 3.2r2
  5. *                            October 30, 1992
  6. *
  7. * NCSA HDF Version 3.2 source code and documentation are in the public
  8. * domain.  Specifically, we give to the public domain all rights for future
  9. * licensing of the source code, all resale rights, and all publishing rights.
  10. *
  11. * We ask, but do not require, that the following message be included in all
  12. * derived works:
  13. *
  14. * Portions developed at the National Center for Supercomputing Applications at
  15. * the University of Illinois at Urbana-Champaign, in collaboration with the
  16. * Information Technology Institute of Singapore.
  17. *
  18. * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
  19. * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
  20. * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
  21. *
  22. ****************************************************************************
  23. */
  24.  
  25. #ifdef RCSID
  26. static char RcsId[] = "@(#)$Revision: 1.5 $";
  27. #endif
  28. /*
  29. $Header: /hdf/hdf/v3.2r2/src/RCS/vgp.c,v 1.5 1992/10/23 00:14:11 koziol beta koziol $
  30.  
  31. $Log: vgp.c,v $
  32.  * Revision 1.5  1992/10/23  00:14:11  koziol
  33.  * Changed all DFIstr*() and DFImem*() calls to HDstr*() and HDmem*() calls
  34.  * #ifdef'd out the macros Jason defined for Hopen, Hclose, etc. for Vsets
  35.  * Replaced Vset VFREESPACE and VGETSPACE calls with actual calls to HDfreespace
  36.  * and HDgetspace
  37.  * Added a MS-Windows lower lower for file I/O (which may not be completely working
  38.  *
  39.  * Revision 1.3  1992/10/12  18:11:51  koziol
  40.  * Updated for v3.2r2 release
  41.  *
  42.  * Revision 1.2  1992/08/27  19:54:56  likkai
  43.  * Vclose now returns an (intn) status.
  44.  *
  45.  * Revision 1.1  1992/08/25  21:40:44  koziol
  46.  * Initial revision
  47.  *
  48. */
  49. /*****************************************************************************
  50. * vgp.c
  51. * Part of the vertex-set interface.
  52. * VGROUPs are handled by routines in here.
  53. *
  54. *************************************************************************/
  55.  
  56. #include "vg.h"
  57. #include "hfile.h"
  58. /* ------------------------------------------------------------ */
  59. /* 
  60. *
  61. * G L O B A L S 
  62. *
  63. * These are the *only* globals in the Vset interface!!  
  64. * They are used only for debugging.  No globals in other files. 
  65. * The 2 functions below turn debugging on and off.
  66. *
  67. */
  68.  
  69. PRIVATE int32 Load_vfile
  70.   PROTO((HFILEID f));
  71.  
  72. PRIVATE void Remove_vfile
  73.   PROTO((HFILEID f));
  74.  
  75. PUBLIC    char         sjs[200];
  76. PUBLIC    int16   vjv    =    0;
  77.  
  78. /*
  79. turn debug on 
  80. */
  81. #ifdef PROTOTYPE
  82. PUBLIC void    setjj (void)          
  83. #else
  84.  
  85. PUBLIC void    setjj()          
  86.  
  87. #endif
  88.  
  89.     vjv=1; 
  90. }
  91.  
  92. /*
  93. turn debug off 
  94. */
  95. #ifdef PROTOTYPE
  96. PUBLIC void    setnojj (void)          
  97. #else
  98.  
  99. PUBLIC void    setnojj()          
  100. #endif
  101.  
  102.     vjv=0; 
  103. }
  104.  
  105.  
  106. /*
  107. * -------------------------------------------------------------------- 
  108. * PRIVATE  data structure and routines.
  109. * Info about all vgroups in the file are loaded into vgtab  at start;
  110. * and the vg field set to NULL until that vgroup is attached,
  111. * and reset back to NULL when that vgroup is detached. 
  112. * Info about all vdatas in the file are loaded into vstab  at start;
  113. * and the vs field set to NULL until that vdata is attached,
  114. * and reset back to NULL when that vdata is detached. 
  115. * -------------------------------------------------------------------- 
  116. */
  117.  
  118.  
  119. PUBLIC vfile_t  vfile [MAX_FILE];
  120.  
  121. /* -------------------------- Load_vfile ------------------------ */
  122. /*
  123.   *** Only called by Vinitialize()  ***   
  124.  
  125. loads vgtab table with info of all vgroups in file f.
  126. Will allocate a new vfile_t, then proceed to load vg instances.
  127. RETURNS -1 if error or no more file slots available.
  128. RETURNS 1 if ok.
  129. */
  130.  
  131. #ifdef PROTOTYPE
  132. PRIVATE int32 Load_vfile (HFILEID f)    
  133. #else
  134.  
  135. PRIVATE int32 Load_vfile (f)              
  136.  
  137.     HFILEID    f;
  138.  
  139. #endif
  140.  
  141. {
  142.     vfile_t          * vf;
  143.     vginstance_t  * v;
  144.     vsinstance_t  * w;
  145.     int32             aid, stat;
  146.     uint16            tag, ref;
  147.     char * FUNC = "Load_vfile";
  148.  
  149.     if (vjv) { sprintf(sjs,"@Load_vfile \n"); zj; }
  150.  
  151.     /* allocate a new vfile_t structure */
  152.         vf = Get_vfile(f);
  153.         if(!vf) return FAIL;
  154.  
  155.     /* load all the vg's  tag/refs from file */
  156.     vf->vgtabn    = -1;
  157.     vf->vgtabtail = &(vf->vgtab);
  158.  
  159.     vf->vgtab.ref      = -1;
  160.     vf->vgtab.nattach  = -1;
  161.     vf->vgtab.nentries = -1;
  162.     vf->vgtab.vg       = NULL;
  163.     vf->vgtab.next     = NULL;
  164.  
  165.     vf->vgtabn = 0;
  166.  
  167.     stat = aid = QQstartread(f, DFTAG_VG,  DFREF_WILDCARD);
  168.     while (stat != FAIL) {
  169.           QQQuerytagref (aid, &tag, &ref);
  170. #ifdef DEBUG
  171.           if (vjv) {
  172.             sprintf(sjs,"#LOADVGDIR:FOUND (%d) <%d/%d>\n ",
  173.                     vf->vgtabn, tag, ref); zj;
  174.           }
  175. #endif          
  176.           if (!(v = (vginstance_t*) HDgetspace (sizeof(vginstance_t)))) {
  177.             HERROR(DFE_NOSPACE);
  178.             return(FAIL);
  179.           }
  180.           
  181.           vf->vgtabtail->next  = v;
  182.           vf->vgtabtail         = v;
  183.           v->next             = NULL;
  184.           v->ref      = (intn) ref;
  185.           v->vg       = (VGROUP*) NULL; /* ie not attached yet */
  186.           v->nattach  = 0;
  187.           v->nentries = 0;
  188.           vf->vgtabn++;
  189.           stat = QQnextread (aid, DFTAG_VG, DFREF_WILDCARD, DF_CURRENT);
  190.     }
  191.     QQendaccess (aid);
  192.  
  193.  
  194.     /* load all the vs's  tag/refs from file */
  195.     vf->vstabn    = -1;
  196.     vf->vstabtail = &(vf->vstab);
  197.  
  198.     vf->vstab.ref      = -1;
  199.     vf->vstab.nattach  = -1;
  200.     vf->vstab.nvertices= -1;
  201.     vf->vstab.vs       = NULL;
  202.     vf->vstab.next     = NULL;
  203.  
  204.     vf->vstabn = 0;
  205.     stat = aid = QQstartread(f, VSDESCTAG,  DFREF_WILDCARD);
  206.     while (stat != FAIL) {
  207.  
  208.           QQQuerytagref (aid, &tag, &ref);
  209.           
  210. #ifdef DEBUG
  211.           if (vjv) {
  212.             sprintf(sjs,"#LOADVSDIR:FOUND (%d) <%d/%d>\n ",
  213.                     vf->vstabn, tag,ref); zj;
  214.           }
  215. #endif
  216.           if (!(w = (vsinstance_t*) HDgetspace (sizeof(vsinstance_t)))) {
  217.             HERROR(DFE_NOSPACE);
  218.             return(FAIL);
  219.           }
  220.           
  221.           vf->vstabtail->next  = w;
  222.           vf->vstabtail        = w;
  223.           w->next     = NULL;
  224.           w->ref      = (intn) ref;
  225.           w->vs       = (VDATA*) NULL; /* ie not attached yet */
  226.           w->nattach  = 0;
  227.           w->nvertices= 0;
  228.           vf->vstabn++;
  229.           stat = QQnextread (aid, VSDESCTAG, DFREF_WILDCARD, DF_CURRENT);
  230.     }
  231.     QQendaccess (aid);
  232.  
  233.     /* file may be incompatible with vset version 2.x. Need to check it */
  234.         if ( ((int32)0 == vf->vgtabn) && ((int32)0 == vf->vstabn) )
  235.           if ( (int32)0 == vicheckcompat (f) ) { /* not compatible */
  236.             sprintf(sjs,"********************************************\n\n"); zj;
  237.             sprintf(sjs,"%cFile incompatible with vset version 2.0\n",7); zj;
  238.             sprintf(sjs,"%cFirst use the utility vcompat on this file\n",7); zj;
  239.             sprintf(sjs,"********************************************\n\n"); zj;
  240. #if 0
  241.             nvfile--;     /* delete the structure for that file */
  242. #endif
  243.             HERROR(DFE_BADOPEN);
  244.             HEreport("This file is incompatible with the current release");
  245.             return(FAIL);
  246.           }
  247.         
  248.     /* otherwise, success */
  249.     return (SUCCEED);
  250.         
  251. } /* Load_vfile */
  252.  
  253. /* ---------------------------- Remove_vfile ------------------------- */
  254. /*
  255.   removes the file ptr from the vfile[] table. 
  256.   *** Only called by Vfinish() ***
  257. */
  258. #ifdef PROTOTYPE
  259. PRIVATE void Remove_vfile (HFILEID f)
  260. #else
  261. PRIVATE void Remove_vfile (f)
  262.     HFILEID f;
  263. #endif
  264. {
  265.     vginstance_t *vginst, *vg1;
  266.     vsinstance_t *vsinst, *vs1;
  267.     vfile_t      *vf=NULL;
  268.  
  269.     char * FUNC = "Remove_vfile";
  270.  
  271.  
  272.     /* Figure out what file to work on */
  273.     vf = Get_vfile(f);
  274.         
  275.     if(vf==NULL)
  276.         return;
  277.         
  278.     /* free vstab and vgtab link-list entries */
  279.     vginst = &(vf->vgtab);
  280.     while (vginst) {
  281.         vg1 = vginst->next;
  282.         if (vginst->vg)  {
  283.             HDfreespace (vginst->vg);
  284.             HDfreespace (vginst);
  285.         }
  286.         vginst = vg1;
  287.     }
  288.  
  289.     vsinst = &(vf->vstab);
  290.     while (vsinst) {
  291.         vs1 = vsinst->next; 
  292.         if (vsinst->vs) {
  293.             HDfreespace (vsinst->vs);
  294.             HDfreespace (vsinst);
  295.         }
  296.         vsinst = vs1; 
  297.     }
  298.         
  299. }  /* Remove_vfile */
  300.  
  301. /* ---------------------------- Vinitialize ------------------------- */
  302. /* should be replaced by HDFopen() or such */
  303. /* is called by DFvsetopen() only */
  304.  
  305. #ifdef PROTOTYPE
  306. PUBLIC void Vinitialize (HFILEID f)
  307. #else
  308.  
  309. PUBLIC void Vinitialize (f)
  310.     HFILEID f;
  311.  
  312. #endif
  313.  
  314. {
  315.     char * FUNC = "Vinitialize";
  316.  
  317.       Load_vfile (f);
  318.     if (vjv) { sprintf(sjs,"@Vinitialize: f=%ld\n", f); zj; }
  319. }
  320.  
  321. /* ---------------------------- Vfinish ------------------------- */
  322. /* should be replaced by HDFclose() or such */
  323. /* is called by DFvsetclose() only */
  324.  
  325. #ifdef PROTOTYPE
  326. PUBLIC void Vfinish (HFILEID f)
  327. #else
  328.  
  329. PUBLIC void Vfinish (f)
  330.     HFILEID f;
  331.  
  332. #endif
  333.  
  334. {
  335.     char * FUNC = "Vfinish";
  336.  
  337.       Remove_vfile (f);
  338.     if (vjv) { sprintf(sjs,"@Vfinish: f=%ld\n", f); zj; }
  339. }
  340.  
  341.  
  342. /* ---------------------------- vginstance ----------------------------- */
  343. /*
  344. * Looks thru vgtab for vgid and return the addr of the vg instance
  345. * where vgid is found.
  346. * RETURNS NULL if error or not found.
  347. * RETURNS vginstance_t pointer if ok.
  348. *
  349. */
  350.  
  351. #ifdef PROTOTYPE
  352. vginstance_t * vginstance (HFILEID f, uint16 vgid)
  353. #else
  354.  
  355. vginstance_t * vginstance (f, vgid)
  356.     HFILEID     f;
  357.     uint16     vgid;
  358.  
  359. #endif
  360.  
  361. {
  362.   register uintn ref;
  363.   register vginstance_t * v;
  364.   vfile_t      * vf;
  365.   char * FUNC = "vginstance";
  366.   
  367.   if (NULL== (vf = Get_vfile(f))) HRETURN_ERROR(DFE_FNF, NULL);
  368.   
  369.   ref = (uintn) vgid;
  370.   for(v = vf->vgtab.next; v; v = v->next) 
  371.     if (v->ref == ref) return(v);
  372.   
  373.   HERROR(DFE_NOMATCH);
  374.   return(NULL);
  375.   
  376. } /* vginstance */
  377.  
  378. /* ------------------------ vexistvg --------------------------- */
  379. /* 
  380. * Tests if a vgroup with id vgid is in the file's vgtab.
  381. * returns FAIL if not found,
  382. * returns TRUE if found.
  383. */
  384.  
  385. #ifdef PROTOTYPE
  386. int32 vexistvg (HFILEID f, uint16 vgid)          
  387. #else
  388.  
  389. int32 vexistvg (f, vgid)          
  390.     HFILEID     f;
  391.     uint16     vgid;
  392.  
  393. #endif
  394.  
  395. {
  396.   char * FUNC = "vexistvg";
  397.   
  398.   if (NULL== (vginstance_t *) vginstance(f,vgid))
  399.     return(FAIL);
  400.   else
  401.     return (TRUE);
  402.   
  403. } /* vexistvg */
  404.  
  405. /* ==================================================================== */
  406. /*
  407. * vpackvg() and vunpackvg() : Packing and unpacking routines.
  408. * For use in retrieving and storing vgroups to/from the HDF file.
  409. *
  410. *    Fields of VGROUP  that gets stored in HDF as a DFTAG_VG data object:
  411. *        int16        nvelt (no of entries )
  412. *        char        vgname[MAXVGNAMELEN]
  413. *     char     vgclass[MAXVGNAMELEN]
  414. *        int16        tag[1..nvelt]        
  415. *        int16        ref[1..nvelt]        
  416. */
  417. /* ==================================================================== */
  418.  
  419. #define INT16SIZE 2
  420. #define UINT16SIZE 2
  421.  
  422. /* ==================================================================== */
  423. /* 
  424. *    vpackvg
  425. *    extracts fields from  a VGROUP struct vg and pack the fields
  426. *  into array buf in preparation for storage in the HDF file.
  427. *
  428. *  NO RETURN VALUES.
  429. */
  430.  
  431. #ifdef PROTOTYPE
  432. void vpackvg (VGROUP *vg, BYTE buf[], int32 *size)
  433. #else
  434.  
  435. void vpackvg (vg, buf, size)
  436.     VGROUP          *vg;    /* vgroup to be saved to file */
  437.     BYTE            buf[];  /* buffer to receive the packed fields */
  438.     int32             *size;    /* the size of buf is returned here */
  439.  
  440. #endif
  441.  
  442. {
  443.     register uint16     i;
  444.     register BYTE        *b, *bb;
  445.     register uint16        uint16var;
  446.     char * FUNC = "vpackvg";
  447.  
  448.     bb = &buf[0];
  449.  
  450.     /* save nvelt */
  451.     b= bb;
  452.     UINT16ENCODE(b,vg->nvelt);
  453.     bb +=UINT16SIZE;
  454.  
  455.     /* save all tags */
  456.     for(i=0;i<vg->nvelt;i++) {
  457.         b= bb;
  458.         UINT16ENCODE(b,vg->tag[i]);
  459.         bb +=UINT16SIZE;
  460.     }
  461.  
  462.     /* save all refs */
  463.     for(i=0;i<vg->nvelt;i++) {
  464.         b= bb;
  465.         UINT16ENCODE(b,vg->ref[i]);
  466.         bb +=UINT16SIZE;
  467.     }
  468.  
  469.     /* save the vgnamelen and vgname - omit the null */
  470.     b= bb;
  471.     uint16var = HDstrlen(vg->vgname);
  472.     UINT16ENCODE(b,uint16var);
  473.     bb +=UINT16SIZE;
  474.  
  475.     HDstrcpy((char*) bb,vg->vgname);
  476.     bb +=  HDstrlen(vg->vgname) ;
  477.  
  478.     /* save the vgclasslen and vgclass- omit the null */
  479.     b= bb;
  480.     uint16var = HDstrlen(vg->vgclass);
  481.     UINT16ENCODE(b,uint16var);
  482.     bb +=INT16SIZE;
  483.  
  484.     HDstrcpy((char*) bb,vg->vgclass);
  485.     bb +=  HDstrlen(vg->vgclass) ;
  486.  
  487.     /* save the expansion tag/ref pair */
  488.     b= bb;
  489.     UINT16ENCODE(b,vg->extag);   /* the vg's expansion tag */
  490.     bb +=UINT16SIZE;
  491.  
  492.     b= bb;
  493.     UINT16ENCODE(b,vg->exref);   /* the vg's expansion ref */
  494.     bb +=UINT16SIZE;
  495.  
  496.     /*  save the vg's version field */
  497.     b= bb;
  498.     UINT16ENCODE(b,vg->version);
  499.     bb +=UINT16SIZE;
  500.  
  501.     /* save the vg's more field */
  502.     b= bb;
  503.     UINT16ENCODE(b,vg->more);
  504.     bb +=UINT16SIZE;
  505.  
  506.     if (vjv) {
  507.         sprintf(sjs,"vpackvg: vgname is [%s]\n",vg->vgname);
  508.         zj;
  509.     }
  510.  
  511.     /* returns the size of total fields saved */
  512.     *size = (int32) (bb - buf) + 1;
  513.  
  514.     if (vjv) {
  515.         sprintf(sjs,"#vpackvg: vg->nvelt=%d\n",vg->nvelt);
  516.         zj;
  517.     }
  518.  
  519. } /* vpackvg */
  520.  
  521. /* ==================================================================== */
  522. /*
  523. *    vunpackvg:
  524. *    Unpacks the fields from a buf (ie a DFTAG_VG data object just 
  525. *    read in from the HDF file), into a VGROUP structure vg.
  526. *
  527. *     Will first zero out vg, unpack fields, then inits as much of 
  528. *  vg as it can.
  529. *
  530. *    NO RETURN VALUES
  531. *
  532. */
  533.  
  534. #ifdef PROTOTYPE
  535. void vunpackvg (VGROUP *vg, BYTE buf[], int32* size)      
  536. #else
  537.  
  538. void vunpackvg (vg, buf, size)      
  539.  
  540.     VGROUP*              vg;    /* vgroup to be loaded with file data */
  541.     BYTE            buf[];     /* must contain a DFTAG_VG data object from file */
  542.     int32*        size;      /* ignored, but included to look like vpackvg() */
  543.  
  544. #endif
  545.  
  546. {
  547.  
  548.     register BYTE      *b, *bb;
  549.     register uint16   i;
  550.     register uint16      uint16var;
  551.     char * FUNC = "vunpackvg";
  552.  
  553.     *size = *size; /* dummy, so that compiler thinks it is used  */
  554.  
  555.     bb = &buf[0];
  556.  
  557.     /* retrieve nvelt */
  558.     b = bb;
  559.     UINT16DECODE(b,vg->nvelt);
  560.     bb+=UINT16SIZE;
  561.  
  562.     /* retrieve the tags */
  563.     for (i=0;i<vg->nvelt;i++) {
  564.         b= bb;
  565.         UINT16DECODE(b,vg->tag[i]);
  566.         bb +=UINT16SIZE;
  567.     }
  568.  
  569.     /* retrieve the refs */
  570.     for (i=0;i<vg->nvelt;i++) {
  571.         b= bb;
  572.         UINT16DECODE(b,vg->ref[i]);
  573.         bb +=UINT16SIZE;
  574.     }
  575.  
  576.     /* retrieve vgname (and its len)  */
  577.     b= bb;
  578.     UINT16DECODE(b,uint16var);
  579.     bb +=UINT16SIZE;
  580.  
  581.         HIstrncpy(vg->vgname, (char*) bb, (int32) uint16var + 1);
  582.     bb += uint16var;
  583.  
  584.     if (vjv) {
  585.         sprintf(sjs,"vunpackvg: vgname is [%s]\n",vg->vgname);
  586.         zj;
  587.     }
  588.  
  589.     /* retrieve vgclass (and its len)  */
  590.     b= bb;
  591.     UINT16DECODE(b,uint16var);
  592.     bb +=UINT16SIZE;
  593.         
  594.         HIstrncpy(vg->vgclass, (char*) bb, (int32) uint16var + 1);
  595.     bb += uint16var;
  596.  
  597.     b = bb;
  598.     UINT16DECODE(b,vg->extag); /* retrieve the vg's expansion tag */
  599.     bb += UINT16SIZE;
  600.  
  601.     b = bb;
  602.     UINT16DECODE(b,vg->exref); /* retrieve the vg's expansion ref */
  603.     bb += UINT16SIZE;
  604.  
  605.     b = bb;
  606.     UINT16DECODE(b,vg->version); /* retrieve the vg's version field */
  607.     bb += UINT16SIZE;
  608.  
  609.     b = bb;
  610.     UINT16DECODE(b,vg->more); /* retrieve the vg's more field */
  611.     bb += UINT16SIZE;
  612.  
  613. } /* vunpackvg */
  614.  
  615.  
  616. /* ----------------------------- Vattach --------------------------- */
  617.  
  618. /*
  619. *     Vattach:
  620. *
  621. *   attaches to an existing vgroup or creates a new vgroup.
  622. *     returns NULL if  error, else ptr to vgroup.
  623. *
  624. *    IGNORE accesstype. (but save it)  
  625. *  if vgid == -1,
  626. *      create a NEW vg if vgdir is not full.
  627. *      Also set nattach =1, nentries=0.
  628. *  if vgid +ve, 
  629. *      look in vgdir to see if already attached,
  630. *      if yes, incr nattach 
  631. *      if not, fetch from file. attach, set nattach=1, netries= val from file 
  632. *
  633. *    In any case, set marked flag to 0.
  634. */
  635.  
  636. #ifdef PROTOTYPE
  637. PUBLIC VGROUP *Vattach (HFILEID f, int32 vgid, char *accesstype)
  638. #else
  639.  
  640. PUBLIC VGROUP *Vattach (f, vgid, accesstype)
  641.     int32     vgid;                /* actual vgroup's vgid or -1 for new vgroup */
  642.     char       *accesstype;     /* ignored */
  643.     HFILEID    f;                 /* HDF file handle */
  644.  
  645. #endif
  646.  
  647. {
  648.     VGROUP            *vg;
  649.     int16           access;
  650.     int32           vgpacksize;
  651.     BYTE            vgpack[sizeof(VGROUP)];
  652.     vginstance_t    * v;
  653.     vfile_t            * vf;
  654.     char * FUNC = "Vattach";
  655.  
  656.     if (f == FAIL)             {HERROR(DFE_ARGS); return(NULL);}
  657.     if (!(vf = Get_vfile(f)))  {HERROR(DFE_FNF); return(NULL);}
  658.  
  659.     if ( accesstype[0]=='R' || accesstype[0]=='r')      access = 'r';
  660.     else if ( accesstype[0]=='W' || accesstype[0]=='w') access = 'w';
  661.     else HRETURN_ERROR(DFE_BADACC, NULL);
  662.  
  663.         if (vgid == -1) {           /******* create a NEW vg in vgdir ******/
  664.           
  665.           if (access=='r') {
  666.             HERROR(DFE_ARGS);
  667.             return(NULL);
  668.           }
  669.           
  670.           /* allocate space for vg, & zero it out */
  671.           if ( (vg = (VGROUP*) HDgetspace (sizeof(VGROUP)) ) == NULL) {
  672.             HERROR(DFE_NOSPACE);
  673.             return(NULL);
  674.           }
  675.  
  676.           /* initialize new vg */
  677.           vg->nvelt         = 0;
  678.           vg->vgname[0]    = '\0';
  679.           vg->f               = f;
  680.           vg->otag         = DFTAG_VG;
  681.           vg->oref           = vnewref(f);  /* create a new unique ref for it */
  682.           if( vg->oref == 0 ) { HERROR(DFE_NOREF); return(NULL); }
  683.           
  684.           vg->access      = access;
  685.           
  686.           vg->marked        = 0;
  687.           vg->vgclass[0]    = '\0';
  688.           vg->extag        = 0;
  689.           vg->exref        = 0;
  690.           vg->more            = 0;
  691.           vg->version        = VSET_VERSION;
  692.           
  693.           /* attach new vg to file's vgtab  */
  694.           if ( NULL == (v = (vginstance_t*) HDgetspace (sizeof(vginstance_t)))) {
  695.             HERROR(DFE_NOSPACE);
  696.             return(NULL);
  697.           }
  698.           
  699.           vf->vgtabtail->next = v;
  700.           vf->vgtabtail          = v;
  701.           vf->vgtabn++;
  702.           v->next     = NULL;
  703.           v->ref    = (intn) vg->oref;
  704.           v->vg          = vg;
  705.           v->nattach    = 1;
  706.           v->nentries    = 0;
  707.           
  708.           return(vg);
  709.     }
  710.  
  711.     else {         
  712.           /******* access an EXISTING vg *********/
  713.           
  714.           if (NULL == (v= vginstance (f,(uint16)vgid))) {
  715.             HERROR(DFE_NOMATCH);
  716.             HEreport("Vgid (%d) is not in vgtab[]", vgid);
  717.             return(NULL);
  718.           }
  719.           
  720.           /*
  721.            * vg already attached.  inc nattach and return existing ptr
  722.            */
  723.           if (v->vg != NULL) {  
  724.             v->nattach++;
  725.             return(v->vg);
  726.           }
  727.           
  728.           /* else vg not attached, must fetch vg from file */
  729.           
  730.           if (QQgetelement(f, DFTAG_VG, (uint16)vgid, vgpack) == (int32)FAIL) {
  731.             HERROR(DFE_NOMATCH);
  732.             return(NULL);
  733.           }
  734.           
  735.           /* allocate space for vg, & zero it out */
  736.           
  737.           if (NULL == (vg =(VGROUP*) HDgetspace (sizeof(VGROUP))) ) {
  738.             HERROR(DFE_NOSPACE);
  739.             return(NULL);
  740.           }
  741.           /*
  742.             zerofill((unsigned char*) vg,sizeof(VGROUP));
  743.             */
  744.           
  745.           /* unpack vgpack into structure vg, and init  */
  746.           
  747.           vunpackvg(vg,vgpack,&vgpacksize);
  748.           vg->f                = f;
  749.           vg->oref            = (uint16)vgid;
  750.           vg->otag         = DFTAG_VG;
  751.           vg->access        = access;
  752.           vg->marked        = 0;
  753.           
  754.           /* attach vg to file's vgtab at the vg instance v */
  755.           v->vg                = vg;
  756.           v->nattach        = 1;
  757.           v->nentries    = vg->nvelt;
  758.           
  759.           return(vg);
  760.     }
  761.         
  762.         
  763. } /* Vattach */
  764.  
  765. /* ---------------------------- Vdetach ---------------------------- */
  766. /* 
  767. *    Vdetach
  768. *    Detaches access to vg.    
  769. *    NO RETURN VALUES
  770. *
  771. *  if marked flag is 1, write out vg to file.
  772. *    if vg still has velts attached to it, cannot detach vg.
  773. *    decr  nattach. if (nattach is 0), free vg from vg instance.
  774. *    (check that no velts are still attached to vg before freeing)
  775. *
  776. *  if attached with read access, just return.
  777. *
  778. * after detach, set marked flag to 0.    
  779. *
  780. */
  781.  
  782. #ifdef PROTOTYPE
  783. PUBLIC void Vdetach (VGROUP *vg)
  784. #else
  785.  
  786. PUBLIC void Vdetach (vg)
  787.     VGROUP *vg;
  788.  
  789. #endif
  790.  
  791. {
  792.  
  793.   int32             vgpacksize;
  794. #if 0
  795.   uint16            u;
  796. #endif
  797.   BYTE                vgpack[sizeof(VGROUP)];
  798.   vginstance_t     * v;
  799.   char * FUNC = "Vdetach";
  800.   
  801.   if ((vg == NULL) || (vg->otag != DFTAG_VG)) {
  802.     HERROR(DFE_ARGS);
  803.     HEprint(stderr, 0);
  804.     return;
  805.   }
  806.   
  807.   /* locate vg's index in vgtab */
  808.   if (NULL ==( v = (vginstance_t*) vginstance (vg->f, vg->oref))) {
  809.     HERROR(DFE_NOVS);
  810.     HEprint(stderr, 0);
  811.     return;
  812.   }
  813.   
  814.   /* update vgroup to file if it has write-access */
  815.   
  816.   /* if its marked flag is 1 */
  817.   /* - OR - */
  818.   /* if that vgroup is empty */
  819.   if (vg->access == 'w') {
  820.     if ((vg->nvelt==0) || (vg->marked == 1)) {
  821.       if (vjv) {
  822.         sprintf(sjs,"@VDETACH: added %d entries in vg..update vg to file\n",
  823.                 vg->nvelt - v->nentries); zj;
  824.       }
  825.       vpackvg(vg,vgpack,&vgpacksize);
  826.  
  827.       /* 
  828.        *  For now attempt to blow away the old one.  This is a total HACK
  829.        *    but the H-level needs to stabilize first
  830.        */
  831.       Hdeldd(vg->f, DFTAG_VG, vg->oref);
  832.       if(vjv) {sprintf(sjs,"OLD VGROUP deleted.  Now writing again\n"); zj;}
  833.  
  834.       if(QQputelement(vg->f, DFTAG_VG, vg->oref, vgpack, vgpacksize) == FAIL) {
  835.         HERROR(DFE_WRITEERROR);
  836.         HEprint(stderr, 0);
  837.       }
  838.       vg->marked = 0;
  839.       return;
  840.     }
  841.   }
  842.   
  843.   v->nattach--;
  844.   if (vjv) { sprintf(sjs,"#Vdetach: nattach is now %d\n", v->nattach); zj; }
  845.   
  846.   if (v->nattach > 0)
  847.     return;    /* ok */
  848.   
  849.   
  850.   /* else, we can detach and remove vg from file's vgtab  */
  851.   
  852. #if 0
  853.   if(vjv) {
  854.     /* check if vg still has attached entries */
  855.     for (u=0; u<vg->nvelt; u++)     
  856.       if (vg->velt[u]) {
  857.         sprintf(sjs,"@Vdetach: vg has vs %d undetached! continuing. \n",u); zj;
  858.         break;
  859.       }
  860.   }
  861. #endif
  862.   v->vg = NULL;             /* detach vg from vgdir */
  863.   
  864.   HDfreespace (vg);
  865.   
  866.   return; /* ok */
  867.   
  868. } /* Vdetach */
  869.  
  870.  
  871. /* ------------------------------ Vinsert ----------------------------- */
  872. /*
  873. *    Vinsert
  874. *  inserts a velt (vs or vg)  into a vg 
  875. *    RETURNS entry position within vg (0 or +ve) or FAIL on error.
  876. *
  877. *    checks and prevents duplicate links.
  878. *
  879. * Since multiple files are now possible, check that both vg and velt
  880. * are from the same file. else error.
  881. */
  882.  
  883. #ifdef PROTOTYPE
  884. PUBLIC int32 Vinsert (VGROUP *vg, VDATA *velt)             
  885. #else
  886.  
  887. PUBLIC int32 Vinsert (vg, velt)             
  888.     VGROUP    *vg;
  889.     VDATA     *velt;            /* (VGROUP*) or (VDATA*), doesn't matter */
  890.  
  891. #endif
  892.  
  893. {
  894.     uint16 u;
  895.     char * FUNC = "Vinsert";
  896.  
  897.     if (vg == NULL || velt == NULL) {
  898.           HERROR(DFE_BADPTR);
  899.           return(FAIL);
  900.         }
  901.  
  902.     if (vg->otag != DFTAG_VG) {
  903.           HERROR(DFE_ARGS);
  904.           return(FAIL);
  905.         }
  906.  
  907.         if(vg->nvelt >= MAXNVELT) {
  908.           HERROR(DFE_VGSIZE);
  909.           return(FAIL);
  910.         }
  911.  
  912.     if ( Get_vfile(vg->f) != Get_vfile(velt->f) ) {
  913.           HERROR(DFE_DIFFFILES);
  914.           return(FAIL);
  915.         }
  916.  
  917.     /* check in vstab  or vgtab that velt actually exist in file */
  918.  
  919.     switch (velt->otag) {
  920.         case VSDESCTAG:
  921.             if (vexistvs (vg->f,velt->oref) == FAIL) 
  922.                   {HERROR(DFE_NOVS); return(FAIL);}
  923.             break;
  924.  
  925.         case DFTAG_VG:
  926.             if (vexistvg (vg->f,velt->oref) == FAIL) 
  927.                   {HERROR(DFE_NOVS); return(FAIL);}
  928.             break;
  929.  
  930.       default:
  931.           HERROR(DFE_ARGS);
  932.           return(FAIL);
  933.     } /* switch */
  934.  
  935.     /* check and prevent duplicate links */
  936.     for(u=0;u<vg->nvelt;u++)
  937.         if ( (vg->tag[u] == velt->otag) && (vg->ref[u] == velt->oref) ) {
  938.            HERROR(DFE_DUPDD);
  939.            HEreport("Vinsert: duplicate link <%d/%d>", velt->otag,velt->oref);
  940.            return(FAIL);
  941.         }
  942.  
  943.     /* Finally, ok to insert */
  944.     vinsertpair (vg, velt->otag, velt->oref);
  945.  
  946.     if (vjv) {
  947.         sprintf(sjs,"#Vinsert:inserted <%d/%d> at nvelt=%d\n",
  948.             velt->otag, velt->oref, vg->nvelt); zj;
  949.     }
  950.  
  951.     vg->marked = TRUE;
  952.     return(vg->nvelt - 1);
  953.  
  954. } /* Vinsert */
  955.  
  956. /* ----------------------------- Vflocate -------------------------------- */
  957. /*
  958. Checks to see if the given field exists in a vdata belonging to this vgroup.
  959. If found, returns the ref of the vdata.
  960. If not found, or error, returns FAIL
  961. 28-MAR-91 Jason Ng NCSA
  962. */
  963.  
  964. #ifdef PROTOTYPE
  965. PUBLIC int32 Vflocate (VGROUP *vg, char *field)
  966. #else
  967.  
  968. PUBLIC int32 Vflocate (vg, field)
  969.     VGROUP * vg;
  970.     char * field;
  971. #endif
  972.  
  973. {
  974.     int32   s;
  975.     uint16  u;
  976.     VDATA     *vs;
  977.     char * FUNC = "Vflocate";
  978.  
  979.     for (u=0;u<vg->nvelt;u++)  {
  980.         if (vg->tag[u] != VSDESCTAG) continue;
  981.         vs = (VDATA*) VSattach (vg->f,vg->ref[u],"r");
  982.         if (vs==NULL) return (FAIL);
  983.         s = VSfexist (vs, field);
  984.         VSdetach (vs);
  985.         if (s==1) return (vg->ref[u]); /* found. return vdata's ref */
  986.     }
  987.  
  988.     return (FAIL); /* field not found */
  989.  
  990. } /* Vflocate */
  991.  
  992. /* ----------------------- Vinqtagref ------------------------------------- */
  993. /*
  994. * Checks whether the given tag/ref pair already exists in the vgroup.
  995. * RETURNS TRUE if exist
  996. * RETURNS FALSE if not.
  997. * 28-MAR-91 Jason Ng NCSA
  998. */
  999. #ifdef PROTOTYPE
  1000. PUBLIC int32 Vinqtagref (VGROUP *vg, int32 tag, int32 ref)
  1001. #else
  1002.  
  1003. PUBLIC int32 Vinqtagref (vg, tag, ref)
  1004.     VGROUP     * vg;
  1005.     int32     tag, ref;
  1006.  
  1007. #endif
  1008.  
  1009. {
  1010.     register intn   i;
  1011.     register uint16     ttag, rref;
  1012.     char * FUNC = "Vinqtagref";
  1013.  
  1014.     ttag = (uint16) tag;
  1015.     rref = (uint16) ref;
  1016.  
  1017.     for (i=0; i < vg->nvelt; i++)
  1018.         if ((ttag == vg->tag[i]) && (rref == vg->ref[i])) 
  1019.             return (TRUE); /* exist */
  1020.  
  1021.     return (FALSE); /* does not exist */
  1022.  
  1023. } /* Vinqtagref */
  1024.  
  1025. /* ------------------------- Vntagrefs ------------------------------- */
  1026. /*
  1027. * Returns the number (0 or +ve integer) of tag/ref pairs in a vgroup.
  1028. * If error, returns FAIL
  1029. * 28-MAR-91 Jason Ng NCSA.
  1030. */
  1031.  
  1032. #ifdef PROTOTYPE
  1033. PUBLIC int32 Vntagrefs (VGROUP *vg)
  1034. #else
  1035.  
  1036. PUBLIC int32 Vntagrefs (vg)
  1037.     VGROUP * vg;
  1038.  
  1039. #endif
  1040.  
  1041. {
  1042.     char * FUNC = "Vntagrefs";
  1043.  
  1044.     return ( (vg->otag == DFTAG_VG) ? (int32) vg->nvelt : FAIL);
  1045.  
  1046. } /* Vntagrefs */
  1047.  
  1048. /* -------------------------- Vgettagrefs ----------------------------- */
  1049. /*
  1050. * Returns n tag/ref pairs from the vgroup into the caller-supplied arrays
  1051. * tagrarray and refarray.
  1052. * n can be any +ve number, but arrays must be this big.
  1053. * RETURNS the total number of (0 or +ve #)  tag/ref pairs returned.
  1054. * 28-MAR-91 Jason Ng NCSA.
  1055. *
  1056. * NOTE: Do not confuse with Vgettagref().
  1057. *
  1058. */
  1059.  
  1060. #ifdef PROTOTYPE
  1061. PUBLIC int32 Vgettagrefs (VGROUP *vg, int32 tagarray[], int32 refarray[], int32 n)
  1062. #else
  1063.  
  1064. PUBLIC int32 Vgettagrefs (vg, tagarray, refarray, n)
  1065.     VGROUP     * vg;
  1066.     int32     n;
  1067.     int32 tagarray[], refarray[];
  1068.  
  1069. #endif
  1070.  
  1071. {
  1072.     int32 i;
  1073.     char * FUNC = "Vgettagrefs";
  1074.  
  1075.     if (n > (int32)vg->nvelt)
  1076.         n = vg->nvelt;
  1077.  
  1078.     for (i=0; i<n; i++) {
  1079.         tagarray[i] = (int32) vg->tag[i];
  1080.         refarray[i] = (int32) vg->ref[i];
  1081.     }
  1082.  
  1083.     return (n);
  1084. } /* Vgettagrefs */
  1085.  
  1086. /* -------------------------- Vgettagref -------------------------------- */
  1087. /*
  1088. * Returns a specified tag/ref pair from the vgroup.
  1089. * User specifies an index. 
  1090. * RETURNS FAIL if OK.
  1091. * RETURNS SUCCEED if error.
  1092. * 12-MAY-91 Jason Ng NCSA.
  1093. *
  1094. * NOTE: Do not confuse with Vgettagrefs().
  1095. *
  1096. */
  1097.  
  1098. #ifdef PROTOTYPE
  1099. PUBLIC int32 Vgettagref (VGROUP *vg, int32 which, int32 *tag, int32 *ref)
  1100. #else
  1101.  
  1102. PUBLIC int32 Vgettagref (vg, which, tag, ref)
  1103.     VGROUP     * vg;
  1104.     int32     which;
  1105.     int32     *tag, *ref; /* these are returned */
  1106.  
  1107. #endif
  1108.  
  1109. {
  1110.     char * FUNC = "Vgettagref";
  1111.  
  1112.     if (vg==NULL) return (FAIL);
  1113.     if (which < 0 || which > (int32)(vg->nvelt-1))
  1114.           return (FAIL); /* range err */
  1115.  
  1116.         *tag  = (int32) vg->tag[which];
  1117.         *ref  = (int32) vg->ref[which];
  1118.     return (SUCCEED); /* ok */
  1119.  
  1120. } /* Vgettagref */
  1121.  
  1122. /* ------------------------ Vaddtagref ---------------------------------- */
  1123. /*
  1124. * Inserts a tag/ref pair into the attached vgroup vg.
  1125. * First checks that the tag/ref is unique.
  1126. * If error, returns FAIL or tag/ref is not inserted.
  1127. * If OK, returns the total number of tag/refs in the vgroup (a +ve integer).
  1128. * 28-MAR-91 Jason Ng NCSA.
  1129. */
  1130.  
  1131. #ifdef PROTOTYPE
  1132. PUBLIC int32 Vaddtagref (VGROUP *vg, int32 tag, int32 ref)
  1133. #else
  1134.  
  1135. PUBLIC int32 Vaddtagref ( vg, tag, ref)
  1136.     VGROUP     * vg;
  1137.     int32     tag, ref;
  1138.  
  1139. #endif
  1140.  
  1141. {
  1142.     int32  n;
  1143.     char * FUNC = "Vaddtagref";
  1144.  
  1145.     if (Vinqtagref (vg, tag, ref) == 1) {
  1146.           /* error, already exists */
  1147.           HERROR(DFE_DUPDD);
  1148.           return (FAIL);
  1149.         }
  1150.     n = vinsertpair (vg, (uint16) tag, (uint16) ref);
  1151.     return (n);
  1152.  
  1153. } /* Vaddtagref */
  1154.  
  1155. /* ------------------------ vinsertpair --------------------------------- */
  1156. /*
  1157. * Inserts a tag/ref pair into the attached vgroup vg.
  1158. * Does not check for errors. 
  1159. * Returns the total number of tag/refs in the vgroup.
  1160. */
  1161.  
  1162. #ifdef PROTOTYPE
  1163. int32 vinsertpair (VGROUP *vg, uint16 tag, uint16 ref)
  1164. #else
  1165.  
  1166. int32 vinsertpair ( vg, tag, ref)
  1167.     VGROUP        * vg;
  1168.     uint16        tag, ref;      /* this MUST be uint16 -  private routine */
  1169.  
  1170. #endif
  1171.  
  1172. {
  1173.     char * FUNC = "vinsertpair";
  1174.  
  1175.     vg->velt[vg->nvelt]  = NULL;
  1176.     vg->tag[vg->nvelt]   = tag;
  1177.     vg->ref[vg->nvelt]   = ref;
  1178.     vg->nvelt ++;
  1179.  
  1180.     vg->marked = TRUE;
  1181.     return ((int32) vg->nvelt);
  1182. }
  1183.  
  1184. /* ==================================================================== */
  1185. /* 
  1186. *     Ventries
  1187. *    returns the no of entries (+ve integer) in the vgroup vgid.
  1188. *  vgid must be an actual id
  1189. *  RETURNS FAIL if error
  1190. *
  1191. *  undocumented
  1192. *
  1193. */
  1194.  
  1195. #ifdef PROTOTYPE
  1196. int32 Ventries (HFILEID f, int32 vgid)    
  1197. #else
  1198.  
  1199. int32 Ventries (f, vgid)    
  1200.     HFILEID    f;
  1201.     int32      vgid;
  1202.  
  1203. #endif
  1204.  
  1205. {
  1206.     BYTE        vgpack[sizeof(VGROUP)];
  1207.     VGROUP     vg;
  1208.     int32       vgpacksize;
  1209.     char * FUNC = "Ventries";
  1210.  
  1211.     if (vgid < 1) {
  1212.       HERROR(DFE_ARGS);
  1213.       return(FAIL);
  1214.       }
  1215.     if ( QQgetelement(f, DFTAG_VG, (uint16)vgid, vgpack) == FAIL) {
  1216.         sprintf(sjs,"@Ventries: cannot get vg from file\n"); zj;
  1217.         return (FAIL);
  1218.     }
  1219.  
  1220.     vunpackvg(&vg,vgpack,&vgpacksize);
  1221.     return( (int32) vg.nvelt);
  1222.  
  1223. } /* Ventries */
  1224.  
  1225. /* ==================================================================== */
  1226. /*
  1227. *    Vsetname
  1228. *     gives a name to the VGROUP vg.
  1229. *
  1230. * NO RETURN VALUES.
  1231. *
  1232. *    truncates to max length of VGNAMELENMAX 
  1233. */
  1234.  
  1235. #ifdef PROTOTYPE
  1236. PUBLIC void Vsetname (VGROUP *vg, char *vgname)   
  1237. #else
  1238.  
  1239. PUBLIC void Vsetname (vg, vgname)   
  1240.     VGROUP    *vg;
  1241.     char        *vgname;
  1242.  
  1243. #endif
  1244.  
  1245. {
  1246.   char * FUNC = "Vsetname";
  1247.   
  1248.   if (vg == NULL) return;
  1249.   if ( HDstrlen(vgname) > VGNAMELENMAX ) {
  1250.     HIstrncpy(vg->vgname, vgname, VGNAMELENMAX);
  1251.     vg->vgname[VGNAMELENMAX]='\0';
  1252.   } 
  1253.   else {
  1254.     HDstrcpy(vg->vgname, vgname);
  1255.   }
  1256.   vg->marked = TRUE;
  1257.   return;
  1258.   
  1259. } /* Vsetname */
  1260.  
  1261. /* ==================================================================== */
  1262. /*
  1263. *    Vsetclass
  1264. *     assigns a class name to the VGROUP vg.
  1265. *
  1266. * NO RETURN VALUES.
  1267. *
  1268. *    truncates to max length of VGNAMELENMAX 
  1269. */
  1270.  
  1271. #ifdef PROTOTYPE
  1272. PUBLIC void Vsetclass (VGROUP *vg, char *vgclass)         
  1273. #else
  1274.  
  1275. PUBLIC void Vsetclass (vg, vgclass)         
  1276.     VGROUP    *vg;
  1277.     char        *vgclass;
  1278.  
  1279. #endif
  1280.  
  1281. {
  1282.   char * FUNC = "Vsetclass";
  1283.   
  1284.   if (vg == NULL) return;
  1285.   if ( HDstrlen(vgclass) > VGNAMELENMAX) {
  1286.     HIstrncpy(vg->vgclass, vgclass,VGNAMELENMAX);
  1287.     vg->vgclass[VGNAMELENMAX]='\0';
  1288.   }
  1289.   else
  1290.     HDstrcpy(vg->vgclass, vgclass);
  1291.   vg->marked = TRUE;
  1292.   return;
  1293.   
  1294. } /* Vsetclass*/
  1295.  
  1296.  
  1297. /* -------------------------------- Visvg --------------------------------- */
  1298. /*
  1299. *     Visvg
  1300. *    tests if an entry in the vgroup vg is a VGROUP, given the entry's id. 
  1301. *
  1302. *    RETURNS TRUE if so
  1303. *    RETURNS FALSE if not, or if error
  1304. *
  1305. */
  1306.  
  1307. #ifdef PROTOTYPE
  1308. PUBLIC int32 Visvg (VGROUP *vg, int32 id) 
  1309. #else
  1310.  
  1311. PUBLIC int32 Visvg (vg, id) 
  1312.     VGROUP    *vg;
  1313.     int32     id;        /* valid id of the entry in question */
  1314. #endif
  1315.  
  1316. {
  1317.   register intn u;
  1318.   register uint16 ID;
  1319.   char * FUNC = "Visvg";
  1320.   
  1321.   ID = (uint16) id;
  1322.  
  1323.   for(u = 0; u < vg->nvelt; u++)
  1324.     if (vg->ref[u] == ID   &&   /* if the ids match, */
  1325.         vg->tag[u] == DFTAG_VG)     /* and it is a vgroup */
  1326.       return (TRUE);
  1327.   
  1328.   return (FALSE);
  1329.   
  1330. } /* Visvg */
  1331.  
  1332. /* ======================================================= */
  1333. /* 
  1334. *    Vgetid
  1335. *    
  1336. *    Given a vgroup's id, returns the next vgroup's id in the file f .
  1337. *    The call Vgetid(f,-1) returns the id of the FIRST vgroup in the file. 
  1338. *
  1339. *    RETURNS -1 if error
  1340. *    RETURNS the next vgroup's id (0 or +ve integer).
  1341. *
  1342. *    This id is actually the "ref" of the vgroup "tag/ref".
  1343. */
  1344.  
  1345. #ifdef PROTOTYPE
  1346. PUBLIC int32 Vgetid (HFILEID f,int32 vgid)         
  1347. #else
  1348.  
  1349. PUBLIC int32 Vgetid (f, vgid)         
  1350.     int32     vgid;                    /* current vgid */
  1351.     HFILEID     f;                        /* HDF file handle */
  1352.  
  1353. #endif
  1354.  
  1355. {
  1356.     vginstance_t * v;
  1357.     vfile_t        * vf;
  1358.     char * FUNC = "Vgetid";
  1359.  
  1360.     if ( vgid < -1 ) {
  1361.           HERROR(DFE_ARGS);
  1362.           return(FAIL);
  1363.         }
  1364.  
  1365.     if (NULL==(vf = Get_vfile(f))) {
  1366.           HERROR(DFE_FNF);
  1367.           return(FAIL);
  1368.         }
  1369.  
  1370.     if (vjv) {
  1371.         sprintf(sjs,"#Vgetid:vgtabn= %ld vgid=%ld\n",vf->vgtabn,vgid);
  1372.         zj;
  1373.     }
  1374.  
  1375.     if (vgid == FAIL) {
  1376.        if (NULL == vf->vgtab.next)
  1377.           return (FAIL);
  1378.        else
  1379.           return( (vf->vgtab.next)->ref); /* rets 1st vgroup's ref */
  1380.     }
  1381.  
  1382.     /* look in vgtab for vgid */
  1383.     v = (vf->vgtab).next;
  1384.     while(NULL != v) {
  1385.         if(v->ref == (uint16)vgid) break;
  1386.         v = v->next;
  1387.     }
  1388.     if (v==NULL)
  1389.         return (FAIL); /* none found */
  1390.     else
  1391.         if( v->next ==NULL)
  1392.             return (FAIL); /* this is the last vg, no more after it */
  1393.         else
  1394.             return((v->next)->ref); /* success, return the next vg's ref */
  1395.  
  1396. } /* Vgetid */
  1397.  
  1398.  
  1399. /* ================================================================= */
  1400. /*
  1401. *    Vgetnext
  1402. *
  1403. *    Given the id of an entry from a vgroup vg, looks in vg for the next
  1404. *    entry after it, and returns its id.
  1405. *    The call Vgetnext (vg,-1) returns the id of the FIRST entry in the vgroup.
  1406. *
  1407. *  Vgetnext will look at only VSET elements in the vgroup.
  1408. *  To look at all links in a vgroup, use Vgettagrefs instead.
  1409. *
  1410. *    RETURNS -1 if error
  1411. *    RETURNS the id of the next entry( 0 or +ve integer)  in the vgroup.
  1412. *
  1413. *    This id is actually the "ref" of the entry's "tag/ref".
  1414. *
  1415. */
  1416.  
  1417. #ifdef PROTOTYPE
  1418. PUBLIC int32 Vgetnext (VGROUP *vg, int32 id)    
  1419. #else
  1420.  
  1421. PUBLIC int32 Vgetnext (vg, id)    
  1422.     VGROUP    *vg;
  1423.     int32     id;        /* actual id of an entry in the vgroup vg */
  1424.  
  1425. #endif
  1426.  
  1427. {
  1428.     register intn  u;
  1429.     char * FUNC = "Vgetnext";
  1430.   
  1431.     if ((id < -1) || (vg == NULL) || (vg->otag != DFTAG_VG)) {
  1432.         HERROR(DFE_ARGS);
  1433.         return(FAIL);
  1434.     }
  1435.   
  1436.     if (vjv) { sprintf(sjs,"#Vgetnext:vg->nvelt is %d\n",vg->nvelt); zj; }
  1437.   
  1438.     if (vg->nvelt == 0) return(FAIL);             /* nothing in vg */
  1439.   
  1440.     if (id == -1) {
  1441.         if ((vg->tag[0] == DFTAG_VG) || (vg->tag[0]==VSDESCTAG))
  1442.             return(vg->ref[0]);       /* id of first entry */
  1443.     }
  1444.   
  1445.     /* look in vg for id */
  1446.     for(u=0;u<vg->nvelt;u++)
  1447.         if ((vg->tag[u] == DFTAG_VG) || (vg->tag[u]==VSDESCTAG)) {
  1448.             if(vg->ref[u] == (uint16)id) {
  1449.                 if (u == (vg->nvelt - 1) )
  1450.                     return(FAIL);
  1451.                 else  {
  1452.                     if ((vg->tag[u+1] == DFTAG_VG) || (vg->tag[u+1]==VSDESCTAG))
  1453.                         return(vg->ref[u+1]);     /* return the id of next entry */
  1454.                     else  return (FAIL);
  1455.                 }
  1456.             }
  1457.         }
  1458.     
  1459.     return (FAIL);
  1460.  
  1461. } /* Vgetnext  */
  1462.  
  1463. /* ================================================================= */
  1464. /*
  1465. *    Vgetname
  1466. *    returns the vgroup's name
  1467. *   ASSUME that vgname has been allocated large enough to hold
  1468. *   the name
  1469. *
  1470. */
  1471.  
  1472. #ifdef PROTOTYPE
  1473. PUBLIC void Vgetname (VGROUP *vg, char *vgname)          
  1474. #else
  1475.  
  1476. PUBLIC void Vgetname (vg, vgname)          
  1477.     VGROUP    *vg;
  1478.     char    *vgname;            /* its name is returned in this var */
  1479.  
  1480. #endif
  1481.  
  1482. {
  1483.     char * FUNC = "Vgetname";
  1484.  
  1485.     if (vg != NULL) HDstrcpy(vgname, vg->vgname);
  1486.     return;
  1487.  
  1488. } /* Vgetname */
  1489. /* ================================================================= */
  1490. /*
  1491. *    Vgetclass
  1492. *    returns the vgroup's class name 
  1493. *   ASSUME that vgclass has been allocated large enough to hold
  1494. *   the name
  1495. *
  1496. */
  1497.  
  1498. #ifdef PROTOTYPE
  1499. PUBLIC void Vgetclass (VGROUP *vg, char *vgclass)  
  1500. #else
  1501.  
  1502. PUBLIC void Vgetclass (vg, vgclass)  
  1503.     VGROUP    *vg;
  1504.     char    *vgclass;    /* its class name is returned in this var */
  1505.  
  1506. #endif
  1507.  
  1508. {
  1509.   char * FUNC = "Vgetclass";
  1510.   
  1511.   if(vg && vgclass) HIstrncpy(vgclass, vg->vgclass, HDstrlen(vg->vgclass) + 1);
  1512.   return;
  1513.  
  1514. } /* Vgetclass*/
  1515.  
  1516. /* ================================================================= */
  1517. /*
  1518. *    Vinquire
  1519. *
  1520. *    General inquiry routine for VGROUP. 
  1521. *
  1522. *    output parameters:
  1523. *            nentries - no of entries in the vgroup
  1524. *            vgname    - the vgroup's name
  1525. *
  1526. *    RETURNS FAIL if error
  1527. *    RETURNS SUCCEED if ok
  1528. *
  1529. */
  1530.  
  1531. #ifdef PROTOTYPE
  1532. PUBLIC int32 Vinquire (VGROUP *vg, int32 *nentries, char *vgname)
  1533. #else
  1534.  
  1535. PUBLIC int32 Vinquire (vg, nentries, vgname)
  1536.     VGROUP    *vg;
  1537.     int32     *nentries;
  1538.     char        *vgname;
  1539.  
  1540. #endif
  1541.  
  1542. {
  1543.   char * FUNC = "Vinquire";
  1544.   
  1545.   if ((vg == NULL) || (vg->otag != DFTAG_VG)) {
  1546.     HERROR(DFE_ARGS);
  1547.     return(FAIL);
  1548.   }
  1549.  
  1550.   HDstrcpy(vgname, vg->vgname);
  1551.   *nentries = vg->nvelt;
  1552.   
  1553.   return(SUCCEED); 
  1554.  
  1555. } /* Vinquire */
  1556.  
  1557. /* ================================================================= */
  1558.  
  1559. /* ---------------------------- Vopen ------------------------- */
  1560. /* 
  1561. * This routine will replace the code segment " Hopen(); Vinitialize(f)".
  1562. * Thus, if Vopen is used, do not call Vinitialize after that.
  1563. * Similar to Hopen().
  1564. * INPUTS: 
  1565. *        char * path     - file name.
  1566. *     int n  access   - type of access. See Hopen().
  1567. *     int16  ndds     - no. of dd blocks. See Hopen().
  1568. *
  1569. * This routine opens the HDF file and initializes it for Vset operations.
  1570. *
  1571. * RETURN VALUE:
  1572. *  if error:  -1 (FAIL).
  1573. *  if successful: the id of the file (>0).
  1574. *
  1575. * See also Vclose().
  1576. *
  1577. * By: Jason Ng 10 Aug 92
  1578. */
  1579. #ifdef OLD_WAY
  1580. #undef Hopen
  1581. #undef Hclose
  1582. #endif
  1583.  
  1584. #ifdef PROTOTYPE
  1585. PUBLIC HFILEID Vopen( char *path, intn access, int16 ndds)
  1586.  
  1587. #else
  1588. PUBLIC HFILEID Vopen (path, access, ndds)
  1589. char         *path;
  1590. intn         access;
  1591. int16     ndds;
  1592.  
  1593. #endif
  1594.  
  1595. {
  1596.     char * FUNC = "Vopen";
  1597.     HFILEID  f;
  1598.  
  1599.       f = Hopen(path, access, ndds);
  1600.    if (f==FAIL) return(FAIL);
  1601.  
  1602.     Vinitialize(f);
  1603.    return (f);
  1604.  
  1605.     }
  1606.  
  1607.  
  1608. /* ---------------------------- Vclose ------------------------- */
  1609. /* 
  1610. * This routine will replace the code segment " Vfinish(f); Hclose(f);".
  1611. * Thus, if Vclose is used, do not call Vfinish before that.
  1612. *
  1613. * This routine closes the HDF file, after it has freed all memory and 
  1614. * updated the file.
  1615. * INPUTS: 
  1616. *     int32   f       - if of HDF file to be closed.
  1617. *
  1618. * RETURN VALUE:  intn status - result of Hopen().
  1619. *
  1620. * See also Vopen().
  1621. *
  1622. * By: Jason Ng 10 Aug 92
  1623. */
  1624.  
  1625. #ifdef PROTOTYPE
  1626. PUBLIC intn Vclose (HFILEID f)
  1627.  
  1628. #else
  1629.  
  1630. PUBLIC intn Vclose (f)
  1631.     HFILEID f;
  1632. #endif
  1633.  
  1634. {
  1635.     char * FUNC = "Vclose";
  1636.    intn status;
  1637.  
  1638.     Vfinish (f);
  1639.     status = Hclose (f);
  1640.  
  1641.     return (status);
  1642.  
  1643. }
  1644.  
  1645.